package com.iflytek.cosmo.ocr.web.controller;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.zip.ZipOutputStream;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.iflytek.cosmo.ocr.common.PageResult;
import com.iflytek.cosmo.ocr.common.config.ArgusProperties;
import com.iflytek.cosmo.ocr.common.constant.CommonConstant;
import com.iflytek.cosmo.ocr.common.debug.TimerCost;
import com.iflytek.cosmo.ocr.common.util.FileUtil;
import com.iflytek.cosmo.ocr.common.util.IpAddress;
import com.iflytek.cosmo.ocr.common.util.JSONUtil;
import com.iflytek.cosmo.ocr.dao.OcrFileDao;
import com.iflytek.cosmo.ocr.model.domain.*;
import com.iflytek.cosmo.ocr.model.entity.OcrDirectoryEntity;
import com.iflytek.cosmo.ocr.model.entity.OcrFileEntity;
import com.iflytek.cosmo.ocr.service.ArgusPostService;
import com.iflytek.cosmo.ocr.service.FileService;
import com.iflytek.cosmo.ocr.support.uap.UapClient;
import com.iflytek.cosmo.ocr.web.vo.CommonParamVO;
import com.iflytek.cosmo.ocr.web.vo.PictureRotateVO;
import com.iflytek.icourt.common.constants.Constants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import static java.util.stream.Collectors.toList;

/**
 * @author liangxu5@iflytek.com
 * @version 1.0
 * @ClassName: FileController.java
 * @Description: 文件相关操作接口
 */
@Api(value = "文件操作API", tags = "文件")
@RestController
@RequestMapping("/file")
public class FileController {
    private static final Logger logger = LoggerFactory.getLogger(FileController.class);

    /**
     * fileService
     */
    @Autowired
    private FileService fileService;
    
    /**
	 * ArgusPostService
	 */
	@Autowired
	private ArgusPostService argusPostService;
	
	/**
	 * ArgusProperties  (zhouwei更改)
	 */
    @Autowired
    private ArgusProperties argusProperties;
    
    @Autowired
    private OcrFileDao ocrFileDao;
    
    @Autowired
    private UapClient uapClient;
    //@Autowired
    //private IpAddress ipAddress;

    /**
     * @param fileId   fileId
     * @param response response
     * @throws Exception Exception
     * @description 文件下載
     * @author liangxu5@iflytek.com
     * @create 2018年9月10日下午2:03:47
     * @version 1.0
     */
    @ApiOperation(value = "文件下载", notes = "文件下载", httpMethod = "GET")
    @RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
    public void downloadFile(HttpServletResponse response, HttpServletRequest request, @RequestParam(name = "fileId", required = true) String fileId)
            throws Exception {
    	String ip = IpAddress.getRemoteIpAddr(request);
        fileService.downloadFile(response, fileId, ip);
    }

    /**
     * @param fileInfo fileInfo
     * @return MessageOutput<Object>
     * @throws Exception Exception
     * @description 文件重命名
     * @author liangxu5@iflytek.com
     * @create 2018年9月10日下午2:05:22
     * @version 1.0
     */
    @ApiOperation(value = "文件重命名", notes = "文件重命名", httpMethod = "POST")
    @RequestMapping(value = "/renameFile", method = RequestMethod.POST)
    public MessageOutput<Object> renameFile(@RequestBody FileInfo fileInfo) throws Exception {
        return fileService.renameFile(fileInfo);
    }

    /**
     * @param fileId fileId
     *
     * @return MessageOutput<Object>
     *
     * @throws Exception Exception
     * @description 文件删除
     * @author liangxu5@iflytek.com
     * @create 2018年9月10日下午2:07:00
     * @version 1.0
     */
    @ApiOperation(value = "文件删除", notes = "文件删除", httpMethod = "POST")
    @RequestMapping(value = "/deleteFile", method = RequestMethod.POST)
    public MessageOutput<Object> deleteFile(@RequestBody CommonParamVO paramVO) throws Exception {
        return fileService.deleteFile(paramVO.getFileId());
    }

    /**
     * @return MessageOutput<Object>
     * @throws Exception Exception
     * @description 获取用户有关的所有文件
     * @author liangxu5@iflytek.com
     * @create 2018年9月10日下午2:07:00
     * @version 1.0
     */
    @ApiOperation(value = "获取用户有关的所有文件", notes = "获取用户有关的所有文件", httpMethod = "POST")
    @RequestMapping(value = "/getAllFile", method = RequestMethod.POST)
    public List<FileInfo> getAllFile(@RequestBody FileInfo fileInfo) throws Exception {
        List<OcrFileEntity> allFile = fileService.getAllFile(fileInfo);
        if (CollectionUtils.isEmpty(allFile)) {
            return new ArrayList<>();
        }
        return allFile.stream().map(this::convert).collect(toList());
    }

    private FileInfo convert(OcrFileEntity entity) {
        if (entity == null) {
            return null;
        }

        FileInfo fileInfo = new FileInfo();
        fileInfo.setDirId(entity.getDirId());
        fileInfo.setFileName(entity.getFileName());
        Integer filePage = entity.getFilePage();
        if (filePage != null) {
            fileInfo.setFilePage(filePage);
        }
        fileInfo.setFilePath(entity.getFilePath());
        Long fileSize = entity.getFileSize();
        if (fileSize != null) {
            fileInfo.setFileSize(fileSize);
        }
        fileInfo.setFileType(entity.getFileType());
        fileInfo.setFormatPath(entity.getFormatPath());
        Long formatSize = entity.getFormatSize();
        if (formatSize != null) {
            fileInfo.setFormatSize(formatSize);
        }
        fileInfo.setFormatType(entity.getFormatType());
        fileInfo.setId(entity.getId());
        fileInfo.setParentId(entity.getParentId());
        Integer status = entity.getStatus();
        if (status != null) {
            fileInfo.setStatus(status);
        }
        fileInfo.setUserId(entity.getUserId());
        fileInfo.setCreateTime(entity.getCreateTime());
        Set<Integer> exampleType=entity.getExampleType();
        if(CollectionUtils.isNotEmpty(exampleType)) {
        	fileInfo.setExampleType(exampleType);
        }

        return fileInfo;
    }

    /**
     * @param fileInfo fileInfo
     * @return MessageOutput<Object>
     * @throws Exception Exception
     * @description 获取父文件下的所有子文件
     * @author liangxu5@iflytek.com
     * @create 2018年9月10日下午2:07:00
     * @version 1.0
     */
    @ApiOperation(value = "获取父文件下的所有子文件", notes = "获取父文件下的所有子文件", httpMethod = "POST")
    @RequestMapping(value = "/getSubFile", method = RequestMethod.POST)
    public List<FileInfo> getSubFile(@RequestBody FileInfo fileInfo) throws Exception {
        List<OcrFileEntity> subFile = fileService.getSubFile(fileInfo);
        if (CollectionUtils.isEmpty(subFile)) {
            return new ArrayList<>();
        }
        return subFile.stream().map(this::convert).collect(toList());
    }

    @ApiOperation(value = "新建文件夹", notes = "新建文件夹", httpMethod = "POST")
    @RequestMapping(value="/createNewDirectory",method = RequestMethod.POST)
    public OutputMessage<Object> createDirectory(@RequestBody OcrDirectoryEntity ocrDirectoryEntity){//httpmessageconvert
        String dirName = ocrDirectoryEntity.getDirName();
        String userId = ocrDirectoryEntity.getUserId();
        return fileService.createDirectory(dirName, userId);
    }

    @ApiOperation(value = "修改文件夹名称", notes = "修改文件夹名称", httpMethod = "POST")
    @RequestMapping (value="/modifyDirectory",method = RequestMethod.POST)
    public OutputMessage<Object> modifyDirectory(@RequestBody OcrDirectoryEntity ocrDirectoryEntity){
        String dirId = ocrDirectoryEntity.getId();
        String dirName = ocrDirectoryEntity.getDirName();
        String userId = ocrDirectoryEntity.getUserId();
        return fileService.modifyDirectory(dirId, dirName, userId);
    }

    @ApiOperation(value = "删除文件夹", notes = "删除文件夹", httpMethod = "POST")
    @RequestMapping(value = "/directory/{dirId}", method = RequestMethod.POST)
    public OutputMessage<Object> deleteDirectory(@PathVariable("dirId") String dirId){
        return fileService.deleteDirectory(dirId);
    }
    /**
     * @return List<OcrDirectoryEntity>
     * @throws Exception Exception
     * @description 获取所有的文件目录
     * @author liangxu5@iflytek.com
     * @create 2018年9月12日下午8:36:47
     * @version 1.0
     */
    @ApiOperation(value = " 获取所有的文件目录", notes = " 获取所有的文件目录", httpMethod = "POST")
    @RequestMapping(value = "/getAllDirectory", method = RequestMethod.POST)
    public List<OcrDirectoryEntity> getAllDirectory(@RequestParam(value = "userId", required=true) String userId,HttpServletRequest request) throws Exception {
        return fileService.getAllDirectory(userId,request);
    }

    // /**
    // * @description
    // * @author liangxu5@iflytek.com
    // * @create 2018年9月18日下午8:13:51
    // * @version 1.0
    // * @param response response
    // * @param exportParams exportParams
    // * @throws Exception Exception
    // */
    // @ApiOperation(value = "导出识别结果", notes = "导出识别结果", httpMethod = "POST")
    // @RequestMapping(value = "/exportFile", method = RequestMethod.POST)
    // public void exportFile(HttpServletResponse response, ExportParams exportParams) throws Exception {
    // fileService.exportFile(response, exportParams);
    // }

    /**
     * @param response     response
     * @param fileId exportParams
     * @throws Exception Exception
     * @description
     * @author liangxu5@iflytek.com
     * @create 2018年9月18日下午8:13:51
     * @version 1.0
     */
    @ApiOperation(value = "导出识别结果", notes = "导出识别结果", httpMethod = "GET")
    @RequestMapping(value = "/exportFile", method = RequestMethod.GET)
    public void exportFile(HttpServletResponse response, String fileId,
                           @RequestParam(value = "type", defaultValue = "word") String fileType) throws Exception {
        fileService.exportFile(response, fileId);
    }

    @ApiOperation(value = "分页检索", notes = "按名称和内容检索")
    @GetMapping("/search")
    public MessageOutput<PageResult<FileInfo>> search(@RequestParam String userId,
                                                      @RequestParam String keyword, @RequestParam(required = false, defaultValue = "true") boolean byName,
                                                      @RequestParam(required = false, defaultValue = "true") boolean byText,
                                                      @RequestParam(required = false, defaultValue = "1") Integer page,
                                                      @RequestParam(required = false, defaultValue = "10") Integer size,
                                                      HttpServletRequest request) {
        if (StringUtils.isBlank(userId)) {
            return new MessageOutput<>(new State(CommonConstant.FAIL_CODE, "userId参数不能为空"));
        }

        PageResult<FileInfo> pageResult = fileService.search(userId, null, keyword, byName, byText, page, size);
        //增加数据埋点
        HttpSession session = request.getSession();
        String keywords = (String) session.getAttribute("keywords");
        Long time = (Long) session.getAttribute("time");
        Long currentTime = System.currentTimeMillis();
        String ip = IpAddress.getRemoteIpAddr(request);
        if ((keywords == null) || (keywords != keyword) || ((keywords == keyword) && (currentTime - time) >= 1000)){
        	if (argusProperties.getBuryingEnable()) { 
        		argusPostService.postAgent(ip, argusProperties.getOcrSearchNum(), 1, "userId=" + userId, null); }
		}
        session.setAttribute("keywords", keyword);
        session.setAttribute("time", currentTime);
        return new MessageOutput<>(new State(CommonConstant.SUCCESS_CODE), pageResult);
    }

    @ApiOperation(value = "标记文件已打开过", notes = "只有当文件第一次打开时才调用")
    @PostMapping("/access/{fileId}")
    public MessageOutput<?> markOpened(@PathVariable String fileId) {
        boolean updateSuccess = fileService.markOpened(fileId);
        int code = updateSuccess ? CommonConstant.SUCCESS_CODE : CommonConstant.FAIL_CODE;
        return new MessageOutput<>(new State(code));
    }

    @ApiOperation(value = "批量删除文件", notes = "批量删除文件")
    @PostMapping("/batchDelete")
    public MessageOutput<?> batchDelete(@RequestBody CommonParamVO paramVO) {
        List<String> fileIds = paramVO.getFileIds();
        if (CollectionUtils.isEmpty(fileIds)) {
            return new MessageOutput<>(new State(CommonConstant.FAIL_CODE, "fileIds参数不能为空"));
        }

        List<String> deleteFailedIds = new ArrayList<>();
        long start=System.currentTimeMillis();
        /*for (String fileId : fileIds) {
            MessageOutput<Object> output = fileService.deleteFile(fileId);
            if (output == null || output.getState().getOk() != CommonConstant.SUCCESS_CODE) {
                deleteFailedIds.add(fileId);
            }
        }*/
        
        
       fileIds.parallelStream().forEach((fileId) ->{
    	   MessageOutput<Object> output = fileService.deleteFile(fileId);
           if (output == null || output.getState().getOk() != CommonConstant.SUCCESS_CODE) {
               deleteFailedIds.add(fileId);
           }
       });
       long end=System.currentTimeMillis();
       System.out.println("共耗时:"+(end-start));

        State state = new State(CommonConstant.SUCCESS_CODE);
        if (CollectionUtils.isNotEmpty(deleteFailedIds)) {
            state.setFailed(deleteFailedIds.stream().collect(Collectors.joining(", ")));
        }

        return new MessageOutput<>(state);
    }

    @ApiOperation(value = "批量下载文件", notes = "批量下载文件")
    @PostMapping("/batch")
    public void batchDownloads(HttpServletResponse response, @RequestParam List<String> fileIds) {
        logger.info("批量下载, fileIds: {}", JSONUtil.toStrByDefault(fileIds));
        response.setContentType("application/octet-stream;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=download.zip");
        response.setStatus(HttpServletResponse.SC_OK);

        try (ZipOutputStream zippedOut = new ZipOutputStream(response.getOutputStream())) {
            Integer writeSize = fileService.writeFilesTo(fileIds, zippedOut);
            if (writeSize != null) {
                response.setContentLength(writeSize.intValue());
            }
            zippedOut.finish();
        } catch (Exception e) {
            logger.warn("批量下载文件异常. fileIds: {}", JSONUtil.toStrByDefault(fileIds), e);
        }
    }

    @ApiOperation("识别结果检查")
    @PostMapping("/export/{fileId}")
    //@TimerCost
    public MessageOutput<?> exportFileCheck(@PathVariable String fileId, @RequestParam String type) throws UnsupportedEncodingException {
        logger.info("识别结果检查. fileId: {}, type: {}", fileId, type);
        //boolean fileExist = fileService.exportCheck(fileId,type);
        MessageOutput<?> outPut= fileService.exportCheckWithMessage(fileId, type);
        return  outPut;
    }

    @ApiOperation("导出Rtf文档或html文档")
    @GetMapping("/exportHtmlAndRtf/{fileId}")
    @TimerCost
    public void exportHtmlAndRtf(@PathVariable String fileId, @RequestParam String type,
                                 HttpServletResponse response, HttpServletRequest request)throws UnsupportedEncodingException{
        logger.info("识别结果导出html rtf. fileId: {}, type: {}", fileId, type);
        ExportFileHtml exportFileHtml = fileService.exportToHtml(fileId, type);
        String fileName = exportFileHtml.getFileName()+"."+type; //中文乱码问题
        try{
            response.setContentType("application/x-msdownload;charset=utf-8");
            response.setCharacterEncoding("UTF-8");
            response.addHeader("Content-Disposition", "attachment;filename=" +new String(fileName.getBytes("UTF-8")));
            for(int i =0;i < exportFileHtml.getOcrResult().size();i++){
                response.getOutputStream().write((exportFileHtml.getOcrResult().get(i)+"\r").getBytes());
                response.getOutputStream().flush();
            }
            response.getOutputStream().close();
        }catch (IOException e){
            logger.error("下载出错",e);
        }
        return;
    }
    @ApiOperation("识别结果导出为文件")
    @GetMapping("/export/{fileId}")
    @TimerCost
    public void exportFile(@PathVariable String fileId, @RequestParam String type,
                           HttpServletResponse response, HttpServletRequest request) throws UnsupportedEncodingException {
        logger.info("识别结果导出. fileId: {}, type: {}", fileId, type);

        String orginalType = type;
        if (StringUtils.equalsIgnoreCase(type, "wps")) {
            type = "docx";
        }
        else if (StringUtils.equalsIgnoreCase(type, "et")) {
            type = "xlsx";
        }

        ExportFileInfo fileInfo = fileService.exportToFile(fileId, type);
        if (fileInfo == null) {
            logger.info("文件导出结果为空. fileId: {}", fileId);
            response.setStatus(404);
            return;
        }
        //增加埋点
        String ip = IpAddress.getRemoteIpAddr(request);
        if (argusProperties.getBuryingEnable()) {
        	OcrFileEntity ocrFileEntity = new OcrFileEntity();
            ocrFileEntity.setId(fileId);
            OcrFileEntity ocrfileInfo = ocrFileDao.selectOne(ocrFileEntity);
            String userId = ocrfileInfo.getUserId();
            switch (type) {
			case "docx":
				argusPostService.postAgent(ip, argusProperties.getOcrExportWordNum(), 1, "userId=" + userId, null);
				break;
			case "wps":
				argusPostService.postAgent(ip, argusProperties.getOcrExportWpsNum(), 1, "userId=" + userId, null);
				break;
			case "pdf":
				argusPostService.postAgent(ip, argusProperties.getOcrExportDoublepdfNum(), 1, "userId=" + userId, null);
				break;
			case "xlsx":
				argusPostService.postAgent(ip, argusProperties.getOcrExportExcelNum(), 1, "userId=" + userId, null);
				break;
			case "et":
				argusPostService.postAgent(ip, argusProperties.getOcrExportEtNum(), 1, "userId=" + userId, null);
				break;
			case "txt":
				argusPostService.postAgent(ip, argusProperties.getOcrExportTxtNum(), 1, "userId=" + userId, null);
				break;
			default:
				break;
			}
        }
        
        byte[] content = fileInfo.getContent();

        // 导出wps/et时, 先生成docx/xlsx文件, 然后更新文件后缀即可
        String fileName = fileInfo.getFileName();
        if (StringUtils.equalsIgnoreCase(orginalType, "wps")) {
            fileName = StringUtils.replace(fileName, "docx", "wps");
        }
        else if (StringUtils.equalsIgnoreCase(orginalType, "et")) {
            fileName = StringUtils.replace(fileName, "xlsx", "et");
        }
        fileName = new String(fileName.getBytes("UTF-8"),"iso-8859-1"); //中文乱码问题

        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
        response.addHeader("Content-Length", "" + content.length);
        response.setContentType("application/octet-stream;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_OK);
        try (ServletOutputStream outputStream = response.getOutputStream()) {
            outputStream.write(content);
            outputStream.flush();
        } catch (Exception e) {
            logger.warn("输出导出结果异常. fileId: {}", fileId, e);
            response.setStatus(404);
        }
        
        return;
    }
    
   
    
    @ApiOperation("合并导出识别结果检查")
    @PostMapping("/mergeExport/check")
    @TimerCost
    public MessageOutput<?> mergeExport(@RequestBody ExportBean exportBean) throws Exception {
    	List<String> fileIds=exportBean.getFileIds();
        logger.info("合并导出mergeExport识别结果检查入参. fileIds: {}", fileIds);
        int totalFilePage = 0;
        for (String fileId : fileIds) {
        	MessageOutput<?> out = fileService.exportCheckWithMessage(fileId,exportBean.getType());
        	if(out.getState().getOk() == CommonConstant.FAIL_CODE) {
        		logger.info("文件校验失败. fileId: {}，失败原因:{}", fileId,out.getState().getFailed());
        		return out;
        	}
        	totalFilePage += Integer.parseInt(out.getState().getFailed());
        }
        //导出文件名获取
  		String fileName=this.fileService.queryDistinctDirName(fileIds);
  		if(StringUtils.isEmpty(fileName)) {
  			logger.info("导出文件夹不唯一！");
  			return new MessageOutput<Object>(new State(CommonConstant.FAIL_CODE,"不支持跨文件夹导出！"),false);
  		}
  		if (totalFilePage > 500){
            return new MessageOutput<Object>(new State(CommonConstant.SUCCESS_CODE, "导出文件总页数最大支持500页"),false);
        }
  		return new MessageOutput<Object>(new State(CommonConstant.SUCCESS_CODE, null),true);
    }

    @ApiOperation("合并导出双层pdf或者WORD接口")
    @PostMapping("/mergeExport")
	public void mergeExportPDF(@RequestParam List<String> fileIds,@RequestParam String type,HttpServletResponse response, HttpServletRequest request)
			throws UnsupportedEncodingException {
    	/*List<String> fileIds=exportBean.getFileIds();
    	String type=exportBean.getType();*/
		logger.info("合并导出双层pdf接口. fileIds: {},type{}", JSON.toJSONString(fileIds),type);
        if (StringUtils.isEmpty(type) || (!Constants.SupportExt.DOCX.equalsIgnoreCase(type) &&
                !Constants.SupportExt.PDF.equalsIgnoreCase(type) || !"wps".equalsIgnoreCase(type))) {
            logger.info("导出类型type必传 ," + Constants.SupportExt.DOCX + "或者是" + Constants.SupportExt.PDF);
            response.setStatus(404);
            return;
        }
		type=type.toLowerCase();
		if (CollectionUtils.isEmpty(fileIds)) {
			logger.info("文件id集合 fileIds为空");
			response.setStatus(404);
			return;
		}

        String originalType = type;
        if (StringUtils.equalsIgnoreCase(type, "wps")) {
            type = "docx";
        }

		String fileName=null;
		//导出文件名获取
		fileName=this.fileService.queryDistinctDirName(fileIds);
		if(StringUtils.isEmpty(fileName)) {
			logger.info("导出文件夹不唯一！");
			response.setStatus(404);
			return;
		}
		fileName=fileName+ "." + originalType;
		List<byte[]> list = new ArrayList<>();
		byte[] all_byte=null;
		if(Constants.SupportExt.DOCX.equalsIgnoreCase(type)) {
			all_byte=fileService.exportToFile(fileIds, type).getContent();
		}else {
			for (String fileId : fileIds) {
				ExportFileInfo fileInfo = fileService.exportToFile(fileId, type);
				if(null!=fileInfo && null!=fileInfo.getContent() && fileInfo.getContent().length >0) {
					byte[] content = fileInfo.getContent();
					list.add(content);
				}else {
					logger.info("文件:{} fileId:{}！没有识别结果",fileInfo.getFileName(),fileId);
					//response.setStatus(404);
					continue;
				}
			}
			if (CollectionUtils.isEmpty(list)) {
				logger.info("文件导出结果为空. fileIds: {}", fileIds);
				response.setStatus(404);
				return;
			}
		}
		/*String fileName = new SimpleDateFormat("yyyyMMddHHmmss")
				.format(new Date()) + "." + type;*/
		try {
			switch (type) {
				case "pdf" :
					all_byte = FileUtil.mergePDFByByte(list, type, fileName);
					break;
				/*case "docx" :
					all_byte = FileUtil.mergeDocByByte(list, type, fileName);
					break;*/
				default :
					break;

			}
		} catch (Exception e1) {
			logger.warn("合并PDF异常. fileIds: {},异常消息{}", fileIds, e1);
			response.setStatus(404);
		}
		// 增加埋点
		String ip = IpAddress.getRemoteIpAddr(request);
		if (argusProperties.getBuryingEnable()) {
			OcrFileEntity ocrFileEntity = new OcrFileEntity();
			ocrFileEntity.setId(fileIds.get(0));
			OcrFileEntity ocrfileInfo = ocrFileDao.selectOne(ocrFileEntity);
			String userId = ocrfileInfo.getUserId();
			switch (type) {
				case "docx" :
					argusPostService.postAgent(ip,
							argusProperties.getOcrExportWordNum(), 1,
							"userId=" + userId, null);
					break;
                case "wps" :
                argusPostService.postAgent(ip,
                        argusProperties.getOcrExportWpsNum(), 1,
                        "userId=" + userId, null);
                    break;
                case "et" :
                argusPostService.postAgent(ip,
                        argusProperties.getOcrExportEtNum(), 1,
                        "userId=" + userId, null);
                    break;
				case "pdf" :
					argusPostService.postAgent(ip,
							argusProperties.getOcrExportDoublepdfNum(), 1,
							"userId=" + userId, null);
					break;
				case "xlsx" :
					argusPostService.postAgent(ip,
							argusProperties.getOcrExportExcelNum(), 1,
							"userId=" + userId, null);
					break;
				case "txt" :
					argusPostService.postAgent(ip,
							argusProperties.getOcrExportTxtNum(), 1,
							"userId=" + userId, null);
					break;
				default :
					break;
			}
		}
		fileName = new String(fileName.getBytes("UTF-8"),"iso-8859-1"); //中文乱码问题
		// //中文乱码问题
		response.setHeader("Content-Disposition",
				"attachment; filename=\"" + fileName + "\"");
		response.addHeader("Content-Length", "" + all_byte.length);
		response.setContentType("application/octet-stream;charset=UTF-8");
		response.setStatus(HttpServletResponse.SC_OK);
		try (ServletOutputStream outputStream = response.getOutputStream()) {
			outputStream.write(all_byte);
			outputStream.flush();
		} catch (Exception e) {
			logger.warn("输出导出结果异常. fileIds: {}", fileIds, e);
			response.setStatus(404);
		}

		return;
	}
    @ApiOperation("识别结果导出为文件压缩包校验")
    @PostMapping("/export/batch/check")
    public MessageOutput<?> exportBatchCheck(@RequestBody ExportBean exportBean) throws Exception {
    	List<String> fileIds=exportBean.getFileIds();
    	String type=exportBean.getType();
    	logger.info("识别结果导出为文件压缩包校验. fileIds: {},type:{}", fileIds,type);
    	int totalFilePage = 0;
        for (String fileId : fileIds) {
        	MessageOutput<?> out = fileService.exportCheckWithMessage(fileId,exportBean.getType());
        	if(out.getState().getOk() == CommonConstant.FAIL_CODE) {
        		logger.info("文件校验失败. fileId: {}，失败原因:{}", fileId,out.getState().getFailed());
        		return out;
        	}
            totalFilePage += Integer.parseInt(out.getState().getFailed());
        }
        //导出文件名获取
  		String fileName=this.fileService.queryDistinctDirName(fileIds);
  		if(StringUtils.isEmpty(fileName)) {
  			logger.info("导出文件夹不唯一！");
  			return new MessageOutput<Object>(new State(CommonConstant.FAIL_CODE,"不允许跨文件夹导出"),false);
  		}
        if (totalFilePage > 500){
            return new MessageOutput<Object>(new State(CommonConstant.SUCCESS_CODE, "导出文件总页数最大支持500页"),false);
        }
  		return new MessageOutput<Object>(new State(CommonConstant.SUCCESS_CODE,null),true);
    }
    
    @ApiOperation("识别结果导出为文件压缩包")
    @PostMapping("/export/batch")
    public void exportBatch(@RequestParam List<String> fileIds,@RequestParam String type,HttpServletResponse response, HttpServletRequest request) throws UnsupportedEncodingException {
    	/*List<String> fileIds=exportBean.getFileIds();
    	String type=exportBean.getType();*/
    	logger.info("识别结果导出为文件或者压缩包. fileIds: {}, type: {}", fileIds, type);
		type=type.toLowerCase();
		if (CollectionUtils.isEmpty(fileIds)) {
			logger.info("文件id集合 fileIds为空");
			response.setStatus(404);
			return;
		}
		String fileName=null;
		//导出文件名获取
		fileName=this.fileService.queryDistinctDirName(fileIds);
		if(StringUtils.isEmpty(fileName)) {
			logger.info("导出文件夹不唯一！");
			response.setStatus(404);
			return;
		}
		final String createFileType=type;
		fileName=fileName+ ".zip";
		List<ExportFileInfo> list = new ArrayList<>();
		fileIds.parallelStream().forEach((fileId) ->{
			ExportFileInfo fileInfo = fileService.exportToFile(fileId, createFileType);
			if(null!=fileInfo && null!=fileInfo.getContent() && fileInfo.getContent().length >0) {
				list.add(fileInfo);
			}else {
				logger.info("文件{}！没有识别结果",fileInfo.getFileName());
				//response.setStatus(404);
				return;
			}
			
		});

		if (CollectionUtils.isEmpty(list)) {
			logger.info("文件导出结果为空. fileIds: {}", fileIds);
			response.setStatus(404);
			return;
		}
		// 增加埋点
		String ip = IpAddress.getRemoteIpAddr(request);
		if (argusProperties.getBuryingEnable()) {
			OcrFileEntity ocrFileEntity = new OcrFileEntity();
			ocrFileEntity.setId(fileIds.get(0));
			OcrFileEntity ocrfileInfo = ocrFileDao.selectOne(ocrFileEntity);
			String userId = ocrfileInfo.getUserId();
			switch (type) {
				case "docx" :
					argusPostService.postAgent(ip,
							argusProperties.getOcrExportWordNum(), 1,
							"userId=" + userId, null);
					break;
				case "wps" :
					argusPostService.postAgent(ip,
							argusProperties.getOcrExportWpsNum(), 1,
							"userId=" + userId, null);
					break;
				case "et" :
					argusPostService.postAgent(ip,
							argusProperties.getOcrExportEtNum(), 1,
							"userId=" + userId, null);
					break;
				case "pdf" :
					argusPostService.postAgent(ip,
							argusProperties.getOcrExportDoublepdfNum(), 1,
							"userId=" + userId, null);
					break;
				case "xlsx" :
					argusPostService.postAgent(ip,
							argusProperties.getOcrExportExcelNum(), 1,
							"userId=" + userId, null);
					break;
				case "txt" :
					argusPostService.postAgent(ip,
							argusProperties.getOcrExportTxtNum(), 1,
							"userId=" + userId, null);
					break;
				default :
					break;
			}
		}
		fileName = new String(fileName.getBytes("UTF-8"),"iso-8859-1"); //中文乱码问题
		
	    response.setContentType("application/octet-stream;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename="+fileName);
        response.setStatus(HttpServletResponse.SC_OK);

        try (ZipOutputStream zippedOut = new ZipOutputStream(response.getOutputStream())) {
            Integer writeSize = fileService.writeExportFileInfoTo(list, zippedOut);
            if (writeSize != null) {
                response.setContentLength(writeSize.intValue());
            }
            zippedOut.finish();
        } catch (Exception e) {
            logger.warn("批量导出文件异常. fileIds: {}", JSONUtil.toStrByDefault(fileIds), e);
        }

    }
    @ApiOperation("创建文件下载异步任务")
    @PostMapping("/createAsyncTask")
    @TimerCost
    public MessageOutput<Object> export(@RequestBody String body, HttpServletRequest request) {
        try {
			JSONObject bodyJson = JSON.parseObject(body);
			String exportFormat = bodyJson.getString("exportFormat");
			JSONArray fileIds = bodyJson.getJSONArray("fileIds");
			boolean isCompress = bodyJson.getBooleanValue("isCompress");
			String userId = bodyJson.getString("userId");

			// 参数合法性校验
			ArrayList<String> validFormats = Lists.newArrayList("docx", "wps", "xlsx", "et", "txt", "pdf");
			if (StringUtils.isBlank(exportFormat) || !validFormats.contains(exportFormat.toLowerCase())) {
			    return new MessageOutput<>(new State(CommonConstant.FAIL_CODE), "参数exportFormat出错");
			}

			if (fileIds == null || fileIds.isEmpty()) {
			    return new MessageOutput<>(new State(CommonConstant.FAIL_CODE), "参数fileIds出错");
			}

			if (StringUtils.isEmpty(userId)) {
			    return new MessageOutput<>(new State(CommonConstant.FAIL_CODE), "参数userId不能为空");
			}
			String[] fileIdArray = fileIds.toArray(new String[fileIds.size()]);
			// 执行文件导出, 返回任务 id
			String taskId = fileService.export(Lists.newArrayList(fileIdArray), exportFormat, isCompress,userId);
			if (taskId == null){
                Map<String,String> map=new HashMap<>();
			    return new MessageOutput<>(new State(CommonConstant.FAIL_CODE), map);
            }

            // 增加埋点
            String ip = IpAddress.getRemoteIpAddr(request);
            if (argusProperties.getBuryingEnable()) {
                switch (exportFormat) {
                    case "docx":
                        argusPostService.postAgent(ip,
                                argusProperties.getOcrExportWordNum(), 1,
                                "userId=" + userId, null);
                        break;
                    case "wps":
                    argusPostService.postAgent(ip,
                            argusProperties.getOcrExportWpsNum(), 1,
                            "userId=" + userId, null);
                        break;
                    case "et":
                    argusPostService.postAgent(ip,
                            argusProperties.getOcrExportEtNum(), 1,
                            "userId=" + userId, null);
                     break;
                    case "pdf":
                        argusPostService.postAgent(ip,
                                argusProperties.getOcrExportDoublepdfNum(), 1,
                                "userId=" + userId, null);
                        break;
                    case "xlsx":
                        argusPostService.postAgent(ip,
                                argusProperties.getOcrExportExcelNum(), 1,
                                "userId=" + userId, null);
                        break;
                    case "txt":
                        argusPostService.postAgent(ip,
                                argusProperties.getOcrExportTxtNum(), 1,
                                "userId=" + userId, null);
                        break;
                    default:
                        break;
                }
            }

			Map<String,String> map=new HashMap<>();
			map.put("taskId", taskId.split("&")[0]);
			map.put("fileName", taskId.split("&")[1]);
			return new MessageOutput<>(new State(CommonConstant.SUCCESS_CODE), map);
		} catch (Exception e) {
			logger.info("创建导出任务异常,异常消息{}",e);
			return new MessageOutput<>(new State(CommonConstant.FAIL_CODE), "创建导出任务异常,异常消息:"+e);
		}
    }
    
    @ApiOperation("高级功能：图片处理接口（歪斜校正&自动旋转、图像切边、分栏切分）")
    @PostMapping("/correctingPic")
    @TimerCost
    public MessageOutput<Object> correctingPic(@RequestParam String fileId,@RequestParam(name="operType") Short operType) throws Exception {
        logger.info("图片处理接口. fileId: {},operType:{}", fileId,operType);
        return this.fileService.correctingPic(fileId, operType);
    }

    @ApiOperation("歪斜图片旋转后展示")
    @RequestMapping(value = "/pictureRotate", method=RequestMethod.POST)
    public OutputMessage<Object> pictureRotate(@RequestBody PictureRotateVO pictureRotateVO){
        String fileId = pictureRotateVO.getFileId();
        String orientation = pictureRotateVO.getOrientation();
        logger.info("图片处理接口. fileId: {},orientation:{}", fileId, orientation);
        return fileService.pictureRotate(fileId, orientation);
    }

    @ApiOperation("接受客户端轮询发送的请求，查看任务是否已经完成。")
    @RequestMapping(value = "/search/task", method=RequestMethod.POST)
    public MessageOutput searchTask(@RequestBody List<String> taskList,HttpServletRequest request){
        logger.info("轮询任务列表. taskList: {},ip:{}", JSONUtil.toStrByDefault(taskList),IpAddress.getRemoteIpAddr(request));

        if (CollectionUtils.isNotEmpty(taskList)) {
            taskList = taskList.stream().filter(id -> StringUtils.isNotBlank(id)).collect(toList());
        }

        if (CollectionUtils.isEmpty(taskList)){
            List<String> list = new ArrayList<>();
            return new MessageOutput(new State(CommonConstant.FAIL_CODE),list);
        }


        MessageOutput taskResult = fileService.searchTask(taskList);
        return  taskResult;
    }
}
